package com.chapter.sample.answer.multiplex.batch;

import jakarta.annotation.Resource;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

@Slf4j
@Component
public class CouponBatchService {
    //下发优惠券数量
    public static final Integer COUPON_NUMBER = 50;

    @Resource
    private ThreadPoolTaskExecutor threadPool;

    /**
     * 下发50条优惠券
     */
    public void batchTaskAction() {
        //1、模拟要下发的50条优惠券，上游系统给我们下发优惠券源头
        List<String> coupons = new ArrayList<>(COUPON_NUMBER);
        for (Integer i = 1; i <= COUPON_NUMBER; i++) {
            coupons.add("优惠券 - " + i);
        }
        //2、创建CountDownLatch，构造器参数为任务数量
        CountDownLatch countDownLatch = new CountDownLatch(coupons.size());
        Long startTime = System.currentTimeMillis() / 1000;
        try {
            //3、将优惠券集合逐条发送进线程池高并发处理
            for (String coupon : coupons) {
                threadPool.execute(() -> {
                    try {
                        //4、交给线程池处理下发业务逻辑，可提出成一个方法
                        System.out.println(String.format("【%s】发送成功", coupon));
                        log.info(MDC.get("coupon"));
                    } finally {
                        //5、发送一个少一个任务，计数减少一个
                        countDownLatch.countDown();
                    }
                });
            }
            //6、阻塞当前发送完毕后，方法才能继续向下走
            countDownLatch.await();
        } catch (Exception e) {
            e.printStackTrace();
        }
        Long endTime = System.currentTimeMillis() / 1000;
        System.out.println("-------任务处理完成costTime：" + (endTime - startTime) + "毫秒");
    }

    @SneakyThrows
    public void batchTaskActionV2() {
        //1、模拟要下发的50条优惠券，上游系统给我们下发优惠券源头
        List<String> coupons = getCoupons();
        Long startTime = System.currentTimeMillis() / 1000;
        //2、调用工具类，批处理任务，这些优惠券coupons，放入线程池threadPool，做什么业务disposeTask下发
        TaskBatchSendUtils.send(coupons,threadPool,TaskBatchSendUtils::disposeTaskV2);
        Long endTime = System.currentTimeMillis() / 1000;
        System.out.println("-------任务处理完成costTime：" + (endTime - startTime) + "毫秒");
    }


    private static List<String> getCoupons() {
        List<String> coupons = new ArrayList<>(COUPON_NUMBER);
        for (Integer i = 1; i <= COUPON_NUMBER; i++) {
            coupons.add("优惠券 - " + i);
        }
        return coupons;
    }
}
